﻿using System.ComponentModel.Composition;
using System.IO;
using System.Threading.Tasks;
using DeepZoomPivotConstructor.VisualLib;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PowerPointRender;
using RenderEngine;
using RenderEngineInterfaces;
using t_TestingLibrary;

namespace t_PowerPointRender
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class t_RenderUsingPowerPoint
    {
        public t_RenderUsingPowerPoint()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        [TestInitialize]
        public void InitForTest()
        {
            t_TestingLibrary.Utilities.MyClassInit();
            t_TestingLibrary.Utilities.AddPart(new RenderControl());
            t_TestingLibrary.Utilities.AddPart(new LayoutHelper());
            t_TestingLibrary.Utilities.AddPart(new TestLogger());
        }

        [TestCleanup]
        public void ShutDownTest()
        {
            t_TestingLibrary.Utilities.MyClassDone();
        }

        [TestMethod]
        public void TestCreation()
        {
            RenderUsingPowerPoint pptr = new RenderUsingPowerPoint();
        }

        [TestMethod]
        [DeploymentItem("test-ppt.ppt")]
        [DeploymentItem("test-pptx.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderPriority()
        {
            RenderUsingPowerPoint pptr = new RenderUsingPowerPoint();
            Assert.AreEqual(RenderPluginPriority.RPPGoodChoice, pptr.RenderPriority(new FileInfo("test-ppt.ppt")), "PPT should render ok!");
            Assert.AreEqual(RenderPluginPriority.RPPGoodChoice, pptr.RenderPriority(new FileInfo("test-pptx.pptx")), "pptx should render ok!");

            FileInfo csFile = new FileInfo("bogus.cs");
            using (var output = csFile.CreateText())
            {
                output.WriteLine("dude");
                output.Close();
            }
            csFile.Refresh();
            Assert.IsTrue(csFile.Exists, "Test file doesn't exist!");
            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, pptr.RenderPriority(csFile), "A cs file can't be rendered by this guy!");

            Assert.AreEqual(RenderPluginPriority.RPPCantDoIt, pptr.RenderPriority(new FileInfo("junk.ppt")), "Non-existant file can't be rendered by this guy!");
        }

        [Export(typeof(IRenderItem))]
        [RenderInfo(typeof(FileInfo))]
        class RenderPDFToOneImage : IRenderItem
        {
            public FileInfo PDFRequested { get; set; }

            public Task<Visual> Render(object what)
            {
                PDFRequested = what as FileInfo;
                return Task<Visual>.Factory.StartNew(() =>
                    {
                        return new VisualSingleImage(new FileInfo("image.jpg"), 300);
                    });
            }

            public RenderPluginPriority RenderPriority(object what)
            {
                FileInfo f = what as FileInfo;
                if (!f.Exists)
                {
                    return RenderPluginPriority.RPPCantDoIt;
                }

                string ext = f.Extension.ToLower();
                if (ext == ".pdf")
                {
                    return RenderPluginPriority.RPPGoodChoice;
                }
                return RenderPluginPriority.RPPCantDoIt;
            }
        }

        [Export(typeof(IRenderItem))]
        [RenderInfo(typeof(string))]
        class RenderStringToOneImage : IRenderItem
        {
            public string StringRequested { get; set; }

            public Task<Visual> Render(object what)
            {
                StringRequested = what as string;
                return Task<Visual>.Factory.StartNew(() =>
                {
                    return new VisualSingleImage(new FileInfo("image.jpg"), 300);
                });
            }

            public RenderPluginPriority RenderPriority(object what)
            {
                var f = what as string;
                return RenderPluginPriority.RPPGeneric;
            }
        }

        [TestMethod]
        [DeploymentItem("test-ppt.ppt")]
        [DeploymentItem("image.jpg")]
        public void TestRenderPPTFile()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            RenderUsingPowerPoint pptr = new RenderUsingPowerPoint();
            t_TestingLibrary.Utilities.Compose(pptr);

            FileInfo f = new FileInfo("test-ppt.ppt");
            var result = pptr.Render(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(1, v.SGNodeList.Count, "Expected a single image!");
        }

        class Params
        {
            [Export("RenderingTempDir")]
            public DirectoryInfo RenderingTempDir { get; set; }
        }

        [TestMethod]
        [DeploymentItem("test-ppt.ppt")]
        [DeploymentItem("image.jpg")]
        public void TestRenderPPTToTempDir()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            DirectoryInfo dir = new DirectoryInfo(".\\TestRenderPPTToTempDir");
            if (dir.Exists)
            {
                dir.Delete();
            }
            dir.Create();
            t_TestingLibrary.Utilities.AddPart(new Params() { RenderingTempDir = dir });
            RenderUsingPowerPoint pptr = new RenderUsingPowerPoint();
            t_TestingLibrary.Utilities.Compose(pptr);

            FileInfo f = new FileInfo("test-ppt.ppt");
            var result = pptr.Render(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(1, v.SGNodeList.Count, "Expected a single image!");
            Assert.AreEqual(1, dir.GetFiles().Length, "Expected 1 image back");
        }

        [TestMethod]
        [DeploymentItem("test-ppt.ppt")]
        [DeploymentItem("image.jpg")]
        public void TestRenderPPTFilePDFIsTemp()
        {
            RenderPDFToOneImage pdfRender = new RenderPDFToOneImage();
            t_TestingLibrary.Utilities.AddPart(pdfRender);
            RenderUsingPowerPoint pptr = new RenderUsingPowerPoint();
            t_TestingLibrary.Utilities.Compose(pptr);

            FileInfo f = new FileInfo("test-ppt.ppt");
            var result = pptr.Render(f).Result;

            Assert.IsNotNull(pdfRender.PDFRequested, "Expected a file to come back!");
            Assert.AreNotEqual(f.Directory.FullName, pdfRender.PDFRequested.Directory.FullName, "Expected rendered PDF to be in a different directory that the clean ppt file!");
        }

        [TestMethod]
        [DeploymentItem("test-pptx.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderPPTxFile()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            RenderUsingPowerPoint pptr = new RenderUsingPowerPoint();
            t_TestingLibrary.Utilities.Compose(pptr);

            FileInfo f = new FileInfo("test-pptx.pptx");
            Assert.IsTrue(f.Exists, "File can't be found");
            var result = pptr.Render(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(1, v.SGNodeList.Count, "Expected a single image!");
        }

        [Import]
        private IRenderEngine MyRender { get; set; }

        [TestMethod]
        [DeploymentItem("test-ppt.ppt")]
        [DeploymentItem("image.jpg")]
        public void TestMetadata()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderUsingPowerPoint());
            t_TestingLibrary.Utilities.Compose(this);

            FileInfo f = new FileInfo("test-ppt.ppt");
            var result = MyRender.RenderToFuture(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(1, v.SGNodeList.Count, "Expected a single image!");
        }

        [TestMethod]
        [DeploymentItem("embeddeditem.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderEmbededWithNolinking()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderUsingPowerPoint());
            t_TestingLibrary.Utilities.Compose(this);

            FileInfo f = new FileInfo("embeddeditem.pptx");
            var result = MyRender.RenderToFuture(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(1, v.SGNodeList.Count, "Expected two single images!");
        }

        [TestMethod]
        [DeploymentItem("embeddeditem.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderOfPPTXEmbdedItem()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderStringToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderUsingPowerPoint());
            t_TestingLibrary.Utilities.Compose(this);

            FileInfo f = new FileInfo("embeddeditem.pptx");
            var result = MyRender.RenderToFuture(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(3, v.SGNodeList.Count, "Expected two single images!");
        }

        [TestMethod]
        [DeploymentItem("nonembeddeditem.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderOfPPTXFakeEmbededItem()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderStringToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderUsingPowerPoint());
            t_TestingLibrary.Utilities.Compose(this);

            FileInfo f = new FileInfo("nonembeddeditem.pptx");
            var result = MyRender.RenderToFuture(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(1, v.SGNodeList.Count, "Expected one single images!");
        }

        [TestMethod]
        [DeploymentItem("embeddedgroupitem.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderOfPPTXGroupEmbdedItem()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderStringToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderUsingPowerPoint());
            t_TestingLibrary.Utilities.Compose(this);

            FileInfo f = new FileInfo("embeddedgroupitem.pptx");
            var result = MyRender.RenderToFuture(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(3, v.SGNodeList.Count, "Expected two single images!");
        }

        [TestMethod]
        [DeploymentItem("embeddedgroupresizeditem.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderOfPPTXGroupResizedEmbdedItem()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderStringToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderUsingPowerPoint());
            t_TestingLibrary.Utilities.Compose(this);

            FileInfo f = new FileInfo("embeddedgroupresizeditem.pptx");
            var result = MyRender.RenderToFuture(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(3, v.SGNodeList.Count, "Expected two single images!");
        }

        [TestMethod]
        [DeploymentItem("embeddeddoublegroupitem.pptx")]
        [DeploymentItem("image.jpg")]
        public void TestRenderOfPPTXDoubleGroupEmbdedItem()
        {
            t_TestingLibrary.Utilities.AddPart(new RenderPDFToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderStringToOneImage());
            t_TestingLibrary.Utilities.AddPart(new RenderUsingPowerPoint());
            t_TestingLibrary.Utilities.Compose(this);

            FileInfo f = new FileInfo("embeddeddoublegroupitem.pptx");
            var result = MyRender.RenderToFuture(f);
            Assert.IsNotNull(result, "expected non-null result from the rendering as a future!");
            Visual v = result.Result;
            Assert.IsNotNull(v, "Expected a visual back! What!?!?!");
            Assert.AreEqual(3, v.SGNodeList.Count, "Expected two single images!");
        }
    }
}
